﻿/**
 * Copyright (c) 2008 michiyasu wada
 * http://www.seyself.com/
 * 
 * Distributed under The MIT License.
 * [http://www.opensource.org/licenses/mit-license.php]
 */

package com.seyself.proxy 
{
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.utils.Proxy;
import flash.utils.flash_proxy;
import flash.utils.getQualifiedClassName;

dynamic public class DisplayNode extends Proxy
{
	
	
	public function DisplayNode(target:DisplayObjectContainer) 
	{
		this._target = target;
	}
	
	
	
	public function toString():String
	{
		var level:uint = arguments[0];
		var n:uint = _target.numChildren;
		var tab:String = "";
		for (var j:uint = 0; j < level;j++ )
		{
			tab += "  ";
		}
		
		var str:String = tab + _target.name +" "+_target.toString() + "\n";
		
		for (var i:uint = 0; i < n; i++ )
		{
			var child:DisplayObject = _target.getChildAt(i);
			if (child is DisplayObjectContainer)
			{
				var node:DisplayNode = new DisplayNode(child as DisplayObjectContainer);
				str += node.toString.apply(node, [level+1]);
			}
			else
			{
				str += tab + tab + child.name + " " + child.toString() + "\n";
			}
		}
		return str;
	}
	
	override flash_proxy function callProperty(methodName:*, ...args):* 
	{
		return _target[methodName].apply(_target, args);
	}
	
	override flash_proxy function getProperty(name:*):* 
	{
		var child:DisplayObject = _target.getChildByName(name);
		if (child is DisplayObjectContainer) 
			return new DisplayNode(child as DisplayObjectContainer);
		return child;
	}
	
	override flash_proxy function setProperty(name:*, value:*):void 
	{
		if(flash_proxy::isAttribute(name)){
			var child:Object = _target.getChildByName(name);
			if (child && child.hasOwnProperty(name))
			{
				child[name] = value;
			}
		} else {
			if (value is DisplayObject)
			{
				value.name = name;
				_target.addChild(value);
			}
		}
	}
	
	override flash_proxy function hasProperty(name:*):Boolean 
	{
		if (_target.getChildByName(name))
			return true;
		return false;
	}
	
	override flash_proxy function deleteProperty(name:*):Boolean 
	{
		var child:DisplayObject = _target.getChildByName(name);
		if (child)
		{
			_target.removeChild(child);
			return true;
		}
		return false;
	}
	
	override flash_proxy function getDescendants(name:*):* 
	{
		if (_target is XML || _target is XMLList)
		{
			return _target..name;
		}
		
		var className:String = getQualifiedClassName(_target);
		throw new TypeError("Error #1016: Descendants 演算子 (..) は型 "+className+" でサポートされていません。");
	}
	
	override flash_proxy function nextNameIndex (index:int):int 
	{
		if (index == 0) {
			_propertiyNameList = [];
			var n:uint = _target.numChildren;
			for (var i:uint = 0; i < n; i++ )
			{
				var child:DisplayObject = _target.getChildAt(i);
				_propertiyNameList.push(child.name);
				_propertiyValueList.push(child);
			}
		}
		
		if (index < _propertiyNameList.length) {
			return index + 1;
		} else {
			return 0;
		}
	}
	
	override flash_proxy function nextName(index:int):String 
	{
		return _propertiyNameList[index - 1];
	}
	
	override flash_proxy function nextValue(index:int):* 
	{
		return _propertiyValueList[index - 1];
	}
	
	private var _target:DisplayObjectContainer;
	private var _propertiyNameList:Array;
	private var _propertiyValueList:Array;
	
	
}

}